package io.github.luons.mediator.core.factory;

import com.fasterxml.jackson.core.type.TypeReference;
import com.google.common.base.Preconditions;
import io.github.luons.mediator.core.factory.http.AbsHttpClientFactory;
import io.github.luons.mediator.core.factory.http.AuthorizationProvider;
import io.github.luons.mediator.core.factory.http.Request;
import io.github.luons.mediator.core.spi.result.ApiResult;
import io.github.luons.mediator.core.utils.ApiHttpClient;
import lombok.Getter;
import lombok.Setter;
import org.apache.http.client.methods.HttpPost;

import java.net.URI;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

@Getter
@Setter
public class HttpClientFactory extends AbsHttpClientFactory {

    private final URI baseUrl;

    private Map<String, Object> headers;

    protected HttpClientFactory(Builder builder, URI baseUrl) {
        super(builder);
        this.baseUrl = baseUrl;
    }

    public static Builder builder() {
        return new Builder();
    }

    public ApiHttpClient newHttpClient() {
        return new ApiHttpClient(this, baseUrl, headers);
    }

    public static class Builder extends BaseHttpBuilder<Builder> {

        private Map<String, Object> headers;

        public Builder headers(Map<String, Object> headers) {
            this.headers = headers;
            return this;
        }

        public HttpClientFactory build() {
            int connectTimeout = 3000;
            Preconditions.checkState((baseUrl != null), ("Base URL is required"));
            maxConnections(connectTimeout).maxConnectionsPerRoute(connectTimeout).connectTimeout(connectTimeout);
            HttpClientFactory factory = new HttpClientFactory(this, URI.create(baseUrl.toString()));
            factory.setHeaders(headers);
            return factory;
        }

        public HttpClientFactory build(Integer connectTimeout) {
            connectTimeout = Objects.isNull(connectTimeout) ? 3000 : connectTimeout;
            Preconditions.checkState((baseUrl != null), ("Base URL is required"));
            maxConnections(connectTimeout).maxConnectionsPerRoute(connectTimeout).connectTimeout(connectTimeout);
            HttpClientFactory factory = new HttpClientFactory(this, URI.create(baseUrl.toString()));
            factory.setHeaders(headers);
            return factory;
        }
    }

    public static void main(String[] args) {
        Map<String, Object> headers = new HashMap<>(2);
        headers.put("Content-Type", "application/json");
        headers.put("x-openapi-pin", Base64.getEncoder().encodeToString("database".getBytes()));
        ApiHttpClient httpClient = HttpClientFactory.builder()
                .baseUrl("http://localhost:8080/v1/api/describeAppInfoList")
                .headers(headers)
                // 如果有Basic 验证则需要实现
                .authorizationProvider(new AuthorizationProvider() {
                    @Override
                    public String getAuthorization() {
                        String encoding = new String(org.apache.commons.codec.binary.Base64.encodeBase64(("user:password").getBytes()));
                        return "Basic " + encoding;
                    }

                    @Override
                    public boolean refreshAuthorization() {
                        return true;
                    }
                }).build(2000).newHttpClient();

        String json = "{\"method\":\"backupSchExecutor\",\"sync\":0,\"jsonData\":\"{\\\"job_param\\\":\\\"{\\\\\\\"uniq_id\\\\\\\":\\\\\\\"13b9fa1da978bf84e47a6d5cea41fcis\\\\\\\"}\\\"}\"}";
        Request<HttpPost> request = httpClient.post();
        request.jsonEntity(json);
        request.header(httpClient.getHeaders());

        Map<String, Object> res = request.execute(new TypeReference<Map<String, Object>>() {
        });
        ApiResult<?> res2 = request.execute(new TypeReference<ApiResult<?>>() {
        });
        System.out.println(res);
    }

}